class BooksController < ApplicationController

  layout 'books_and_chunks'
  before_filter :authenticate_user!
  before_filter :user_allowed_to_edit?, :only => [:edit, :new_edition, :update, :close, :destroy]
  before_filter :find_all_users, :only => [:new, :edit, :new_edition]

  # GET /books
  # GET /books.json
  def index
    @books = current_user.books

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @books }
    end
  end

  # GET /books/search
  def search
    @search = []

    query = params[:keyword].strip

    unless query.empty?
      search_array = query.split

      book_table = Book.arel_table
      user_table = User.arel_table
      chunk_table = Chunk.arel_table

      search_array.each do |word|
        Book.where(book_table[:title].matches("%#{word}%").or(book_table[:genre].matches("%#{word}%")).or(book_table[:abstract].matches("%#{word}%")).or(book_table[:tags].matches("%#{word}%")).or(book_table[:published].matches("%#{word}%"))).each do |hit|
          #Nur hinzufügen wenn noch nicht in der Liste
          @search << hit unless @search.include?(hit)
        end
        User.where(user_table[:username].matches("%#{word}%")).each do |user|
          user.books.each do |hit|
            @search << hit unless @search.include?(hit)
          end
        end
        Chunk.where(chunk_table[:title].matches("%#{word}%")).each do |hit|
          @search << hit.book unless @search.include?(hit.book)
        end
      end
    end

    respond_to do |format|
      format.html { render :search, layout: false }
      format.json { render :json => [@search] }
    end
  end

# GET /books/search_extended
  def search_extended
    title = params[:title].strip
    chunk_title = params[:chunkTitle].strip
    genre = params[:genre].strip
    author = params[:author].strip
    tags = params[:tags].strip
    year = params[:year].strip
    combine_by_or = params[:combineByOr]

    @search = []

    unless title.empty? && genre.empty? && author.empty? && tags.empty? && year.empty? && chunk_title.empty?
      book_table = Book.arel_table
      chunk_table = Chunk.arel_table
      user_table = User.arel_table

      if combine_by_or == 'true' || combine_by_or == '1'
        #OR-Suche

        query = (title.empty? ? nil : book_table[:title].matches("%#{title}%"))
        query = (query.nil? ? book_table[:genre].matches("%#{genre}%") : query.or(book_table[:genre].matches("%#{genre}%"))) unless genre.empty?
        query = (query.nil? ? book_table[:tags].matches("%#{tags}%") : query.or(book_table[:tags].matches("%#{tags}%"))) unless tags.empty?
        query = (query.nil? ? book_table[:published].matches("%#{year}%") : query.or(book_table[:published].matches("%#{year}%"))) unless year.empty?

        results = (query.nil? ? [] : Book.where(query))

        unless chunk_title.empty?
          Chunk.where(chunk_table[:title].matches("%#{chunk_title}%")).each do |chunk|
            results << chunk.book
            printf 'book added: ' + chunk.book.title
          end
        end

        unless author.empty?
          User.where(user_table[:username].matches("%#{author}%")).each do |author|
            author.books.each do |book|
              results << book
              printf 'book added: ' + book.title
            end
          end
        end
      else
        #AND-Suche

        results = []
        results_users = []
        results_books = nil

        unless chunk_title.empty?
          Chunk.where(chunk_table[:title].matches("%#{chunk_title}%")).each do |chunk|
            results << chunk.book
            printf 'book added: ' + chunk.book.title
          end
        end

        unless author.empty?
          User.where(user_table[:username].matches("%#{author}%")).each do |author|
            author.books.each do |book|
              results_users << book
              printf 'book added: ' + book.title
            end
          end
        end

        if results.empty?
          results = results_users
        else
          #Durchschnitt der Ergebnis-Mengen
          results = (results & results_users) unless results_users.empty?
        end

        unless title.empty? && genre.empty? && tags.empty? && year.empty?
          query = (title.empty? ? nil : book_table[:title].matches("%#{title}%"))
          query = (query.nil? ? book_table[:genre].matches("%#{genre}%") : query.and(book_table[:genre].matches("%#{genre}%"))) unless genre.empty?
          query = (query.nil? ? book_table[:tags].matches("%#{tags}%") : query.and(book_table[:tags].matches("%#{tags}%"))) unless tags.empty?
          query = (query.nil? ? book_table[:published].matches("%#{year}%") : query.and(book_table[:published].matches("%#{year}%"))) unless year.empty?

          results_books = (query.nil? ? [] : Book.where(query))
        end

        if results.empty?
          results = results_books
        else
          #Durchschnitt der Ergebnis-Mengen
          results = (results & results_books) unless results_books.nil?
        end
      end

      results.each do |hit|
          @search << hit unless @search.include?(hit)
      end
    end
    respond_to do |format|
      format.html { render :search, layout: false }
      format.json { render json: [@search] }
    end
  end

  # GET /books/1
  # GET /books/1.json
  def show
    @book = Book.find(params[:id])

    respond_to do |format|
      format.html { render_check_template }
      format.json { render json: @book }
    end
  end

  def print
    @book = Book.find(params[:id])

    respond_to do |format|
      format.pdf do
        render :pdf => @book.title, :layout => 'print'
      end
    end

  end

  # GET /books/new
  # GET /books/new.json
  def new
    @book = Book.new

    respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @book }
    end
  end

  # GET /books/1/edit
  def edit
    @book = Book.find(params[:id])

    unless @book.closed?
      render_check_template
    else
      flash[:error] = I18n.t('views.book.flash_errors.book_is_closed')
      render_check_template 'show'
    end
  end

  # POST /books
  # POST /books.json
  def create
    @book = Book.new(params[:book])

    old_book_id = session[:old_book_id]

    respond_to do |format|
      if @book.save
        unless old_book_id.nil?
          old_book = Book.find(old_book_id)
          old_book.chunks.each do |old_chunk|
            chunk = Chunk.new(old_chunk.sliced_attributes)
            chunk.book = @book
            chunk.save
            @book.chunks << chunk
          end
          session[:old_book_id] = nil
        end
        format.html { redirect_to @book, notice: I18n.t('views.book.flash_messages.book_was_successfully_created') }
        format.json { render json: @book, status: :created, location: @book }
      else
        format.html do
          @users ||= User.all
          render action: 'new'
        end
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  # PUT /books/1
  # PUT /books/1.json
  def update
    @book = Book.find(params[:id])

    if params[:update_chunk_order_only] == 'true'
      chunk_ids = params[:chunk_order].split(',')
      chunk_ids.each_with_index do |chunk_id, i|
        chunk = Chunk.find(chunk_id)
        chunk.update_attribute(:position, i)
      end
    else
      params[:book][:user_ids] ||= []
    end

    respond_to do |format|
      if params[:update_chunk_order_only] == 'true'
        format.html { render 'show', layout: false }
      else
        if @book.update_attributes(params[:book])
          format.html { redirect_to @book, notice: I18n.t('views.book.flash_messages.book_was_successfully_updated') }
          format.json { head :no_content }
        else
          format.html { render action: "edit" }
          format.json { render json: @book.errors, status: :unprocessable_entity }
        end
      end
    end
  end

  def close
    @book = Book.find(params[:id])

    respond_to do |format|
      if @book.update_attributes(:closed => true, :published => Time.now)
        format.html { redirect_to @book, notice: I18n.t('views.book.flash_messages.book_was_successfully_closed') }
        format.json { head :no_content }
      else
        format.html { render action: "edit" }
        format.json { render json: @book.errors, status: :unprocessable_entity }
      end
    end
  end

  def new_edition
    old_book = Book.find(params[:id])
    @book = Book.new(old_book.sliced_attributes)
    @book.users = old_book.users

    session[:old_book_id] = old_book.id
    render 'new'
  end

# DELETE /books/1
# DELETE /books/1.json
  def destroy
    @book = Book.find(params[:id])
    @book.destroy

    respond_to do |format|
      format.html { redirect_to books_url }
      format.json { head :no_content }
    end
  end

  private
  def find_all_users
    @users = User.all
  end

  private
  def user_allowed_to_edit?
    user = ckeditor_current_user
    book = Book.find(params[:id])
    if book.users_list.exclude?(user.username)
      flash[:error] = "you not allowed to edit the book"
      redirect_to book_path
    end
  end

end
